﻿#include <iostream>
#include <vector>
#include <string>
using namespace std;



/*

https://leetcode.cn/problems/target-sum/


给你一个整数数组 nums 和一个整数 target 。

向数组中的每个整数前添加 '+' 或 '-' ，然后串联起所有整数，可以构造一个 表达式 ：

例如，nums = [2, 1] ，可以在 2 之前添加 '+' ，在 1 之前添加 '-' ，然后串联起来得到表达式 "+2-1" 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

 

示例 1：
输入：nums = [1,1,1,1,1], target = 3
输出：5
解释：一共有 5 种方法让最终目标和为 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3


示例 2：
输入：nums = [1], target = 1
输出：1
 

提示：
1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000
*/


class Solution {
public:
    vector<vector<int>> dp;

    int solve(const vector<int>& nums, int target, int idx) {
        if (idx < 0) return 0;
        if (dp[idx][target+1010] != -1) return dp[idx][target+ 1010];
        int val = nums[idx];
        if (idx == 0 && target == val && val == 0) { dp[idx][target + 1010] = 2; return  dp[idx][target + 1010]; }
        if (idx == 0 && target == val) { dp[idx][target + 1010] = 1; return  dp[idx][target + 1010];}
        if (idx == 0 && target == -val) { dp[idx][target + 1010] = 1; return  dp[idx][target + 1010]; }
      
        dp[idx][target + 1010] = solve(nums, target - val, idx - 1) + solve(nums, target + val, idx - 1);

        return dp[idx][target+ 1010];
    }

    int findTargetSumWays(vector<int>& nums, int target) {
        dp.resize(22, vector<int>(2030, -1));
        int n = nums.size()-1;
        solve(nums, target,n);

        return dp[n][target+ 1010];
    }
};

//int main() {
//    Solution  s;
//    vector<int> v{ 1,1,1,1,1 };
//    cout << s.findTargetSumWays(v, 3) << endl;
//
//
//    return 0;
//}